package com.sys.common.aop;

import com.alibaba.fastjson.JSON;
import com.sys.common.util.HttpContextUtils;
import com.sys.common.util.IPUtils;
import com.sys.common.util.JwtUtil;
import com.sys.pojo.Log;
import com.sys.service.LogService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;

@Aspect
@Component
@Slf4j
public class SysLogAspect {

    @Resource
    private LogService LogService;

    //切点
    @Pointcut("@annotation(com.sys.common.aop.Operation)")
    public void logPoinCut() {

    }

    //切面 配置通知
    @AfterReturning("logPoinCut()")
    public void saveSysLog(JoinPoint joinPoint) {

        //保存日志
        Log log = new Log();
        //从切面织入点处通过反射机制获取织入点处的方法
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        //获取切入点所在的方法
        Method method = signature.getMethod();
        //获取操作
        Operation operation = method.getAnnotation(Operation.class);
        if (operation != null) {
            String value = operation.value();
            log.setOperation(value);//保存获取的操作
        }

        //获取请求的类名
        String className = joinPoint.getTarget().getClass().getName();
        //获取请求的方法名
        String methodName = method.getName();
        log.setMethod(className + "." + methodName);
        //请求的参数
        Object[] args = joinPoint.getArgs();
        //将参数所在的数组转换成json
        String params = null;
        try {
            params = JSON.toJSON(args).toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (params == null) {
            log.setParams("无参数");
        } else {
            log.setParams(params);
        }
        //获取用户ip地址
        HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
        log.setIp(IPUtils.getIpAddr(request));
        //真实地址

        Object principal = SecurityUtils.getSubject().getPrincipal();
        JwtUtil jwtUtil = new JwtUtil();

        Object username = jwtUtil.decode((String) principal).get("username");
        Object uId = jwtUtil.decode((String) principal).get("uId");
        log.setUserName((String) username);
        log.setCreateBy((Integer) uId);
        LogService.add(log);
    }
}